package com.zxj.camerapreview;

import android.animation.ObjectAnimator;
import android.animation.PropertyValuesHolder;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.pm.PackageManager;
import android.graphics.ImageFormat;
import android.graphics.PixelFormat;
import android.hardware.Camera;
import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioRecord;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;

import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.locks.ReentrantLock;

import cn.iotnova.opus.utils.OpusRecorderTask;
import cn.iotnova.rtc.AudioRecordManager;
import cn.iotnova.rtc.Rtcclient;

//https://blog.csdn.net/byhook/article/details/84037338
//width:1080,height:2019
//YUV420SP(NV21)
//YUV420P(YV12)

public class NativeSfu2Activity extends AppCompatActivity implements SurfaceHolder.Callback, Camera.PreviewCallback {

    private static final String TAG = NativeSfu2Activity.class.getName();
    private SurfaceView mSurfaceView;
    private SurfaceHolder mHolder;
    private Camera mCamera;
    private Camera.Parameters mParameters;
    private int camera_status = 0;

    Rtcclient rtcclient = new Rtcclient();

    Button btn_record;


    private String APP_PATH;
    private String APP_RECORDER_FILE_PATH;
    OpusRecorderTask opusRecorderTask = null;
    private String recorderFilePath;
    private String recorderPcmFilePath;
    private String recorderDecodedPcmFilePath;
    private AudioManager audioManager;
    private int permissionRequestCode;

    int width = 640;
    int height = 480;
    //int width = 480;
    //int height = 640;
    //int width = 1080;
    //int height = 2019;
    private Toast toast;

    private final void toast(String msg) {
        if (toast != null) {
            toast.cancel();
            toast = null;
        }

        toast = Toast.makeText((Context)this, (CharSequence)msg, Toast.LENGTH_LONG);
        toast.show();
    }

    @SuppressLint("NewApi")
    private final void startRecorder() {
        if (checkSelfPermission("android.permission.RECORD_AUDIO") == PackageManager.PERMISSION_DENIED) {
            //toast(getString(R.string.record_permission_denied));
            requestPermissions(new String[]{"android.permission.RECORD_AUDIO", "android.permission.READ_EXTERNAL_STORAGE", "android.permission.WRITE_EXTERNAL_STORAGE"}, this.permissionRequestCode);
        } else if (opusRecorderTask != null) {
            //toast(getString(R.string.play_error));
        } else {
            btn_record.setText("停止录制");
            //playPcmBtn.setEnabled(false);
            //playBtn.setEnabled(false);
            opusRecorderTask = new OpusRecorderTask(recorderFilePath, recorderPcmFilePath, rtcclient);
            (new Thread(opusRecorderTask)).start();
        }
    }

    @SuppressLint("NewApi")
    private final void stopRecorder() {
        //recorderBtn.setText(getString(R.string.start_record));
        btn_record.setText("开始录制");
        //playPcmBtn.setEnabled(true);
        //playBtn.setEnabled(true);
        if (opusRecorderTask != null) {
            opusRecorderTask.stop();
            opusRecorderTask = null;
        }

    }


    //public final static int AUDIO_SAMPLE_RATE = 8000; // 44.1KHz,普遍使用的频率
    //public final static int AUDIO_SAMPLE_RATE = 16000; // 44.1KHz,普遍使用的频率

    //声道数
    //public final static int CHANNELS = 1;

    //public final static int CHANNEL_CONFIG = AudioFormat.CHANNEL_IN_MONO;

    //public final static int AUDIO_FORMAT = AudioFormat.ENCODING_PCM_16BIT;

    //int bufferSizeInBytes = AudioRecord.getMinBufferSize(OpusRecorderTask.AUDIO_SAMPLE_RATE, OpusRecorderTask.CHANNEL_CONFIG, OpusRecorderTask.AUDIO_FORMAT);

    int bufferSizeInBytes = AudioRecord.getMinBufferSize(OpusRecorderTask.DEFAULT_AUDIO_SAMPLE_RATE,
            OpusRecorderTask.channelConfig, AudioFormat.ENCODING_PCM_16BIT);



    public void startRecord() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                //AudioRecordManager.getInstance(NativeSfu2Activity.this, rtcclient).startRecord();
                startRecorder();
            }
        }).start();

    }

    //https://blog.csdn.net/weixin_43889841/article/details/101750935
    @SuppressLint("NewApi")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.sfumain);
        mSurfaceView = (SurfaceView)findViewById(R.id.surfaceView);
        mHolder = mSurfaceView.getHolder();
        mHolder.addCallback(this);
        mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        rtcclient.setSfuActivity(this);

        new Thread(new Runnable() {
            @Override
            public void run() {
                //rtcclient.ConnectToServer(4, bufferSizeInBytes, "192.168.1.6");
                rtcclient.ConnectToServerByCfg(4, bufferSizeInBytes, OpusRecorderTask.DEFAULT_AUDIO_SAMPLE_RATE, OpusRecorderTask.DEFAULT_AUDIO_SAMPLE_RATE,OpusRecorderTask.DEFAULT_OPUS_CHANNEL,"192.168.1.6");
            }
        }).start();

        btn_record = findViewById(R.id.btn_record);

        btn_record.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {

//                if (opusRecorderTask == null) {
//                    startRecorder();
//                } else {
//                    stopRecorder();
//                }
                //AudioRecordManager.getInstance(NativeSfuActivity.this, rtcclient).startRecord();
            }
        });



        audioManager = getSystemService(AudioManager.class);


        //TAG = getClass().getSimpleName();
        //APP_PATH = Environment.getExternalStorageDirectory().toString() + File.separator + "opusaudiodemo" + File.separator;
        APP_PATH = getFilesDir().toString() + File.separator + "opusaudiodemo" + File.separator;
        APP_RECORDER_FILE_PATH = APP_PATH + "recorder_file" + File.separator;

        recorderFilePath = APP_RECORDER_FILE_PATH + "recorder.ops";
        recorderPcmFilePath = APP_RECORDER_FILE_PATH + "recorder.pcm";
        recorderDecodedPcmFilePath = APP_RECORDER_FILE_PATH + "recorderDecoded.pcm";
        permissionRequestCode = 10;
        //AudioRecordManager.getInstance().startRecord("");

//        opusRecorderTask = new OpusRecorderTask(recorderFilePath, recorderPcmFilePath, rtcclient);
//        (new Thread(opusRecorderTask)).start();

        //startRecorder();

    }

    public void onChangeClick(View view) {
//        PropertyValuesHolder valuesHolder2 = PropertyValuesHolder.ofFloat("rotationX", 0.0f, 360.0f, 0.0F);
        PropertyValuesHolder valuesHolder = PropertyValuesHolder.ofFloat("rotationY", 0.0f, 360.0f, 0.0F);
        PropertyValuesHolder valuesHolder1 = PropertyValuesHolder.ofFloat("scaleX", 1.0f, 0.5f,1.0f);
        PropertyValuesHolder valuesHolder3 = PropertyValuesHolder.ofFloat("scaleY", 1.0f, 0.5f,1.0f);
        ObjectAnimator objectAnimator = ObjectAnimator.ofPropertyValuesHolder(mSurfaceView,  valuesHolder,valuesHolder1,valuesHolder3);
        objectAnimator.setDuration(5000).start();
    }

    public void onSwitchClick(View view) {
        camera_status ^= 1;
        if (mCamera != null) {
            mCamera.stopPreview();
            mCamera.release();
        }
        mCamera = Camera.open(camera_status);
        try {
            mCamera.setDisplayOrientation(90);
            mCamera.setPreviewDisplay(mSurfaceView.getHolder());
        } catch (IOException e) {
            e.printStackTrace();
        }
        mCamera.startPreview();
    }

    //https://blog.csdn.net/qq_16775897/article/details/101620194
    byte[] frameBuffer;
    @Override
    public void surfaceCreated(@NonNull SurfaceHolder surfaceHolder) {
        Log.e(TAG,"surfaceCreated");
        try {
            frameBuffer = new byte[((width * height) * ImageFormat.getBitsPerPixel(ImageFormat.NV21)) / 8];

            // Open the Camera in preview mode
            mCamera = Camera.open(camera_status);
            Camera.Parameters param = mCamera.getParameters();

            //https://www.jianshu.com/p/f07a42e1dd0a
            List<Camera.Size> listSize = param.getSupportedPreviewSizes();
            for (Camera.Size size : listSize) {
                System.out.println(size.width + "--------------------" + size.height);
            }


            param.setPictureFormat(PixelFormat.JPEG); //Sets the image format for picture 设定相片格式为JPEG，默认为NV21
            //param.setPreviewFormat(ImageFormat.NV21); //Sets the image format for preview picture，默认为NV21
            param.setPreviewFormat(ImageFormat.NV21); //Sets the image format for preview picture，默认为NV21
            //param.setPictureFormat(PixelFormat.RGBA_8888);
            //param.setPictureFormat(PixelFormat.RGB_565);
            //param.setPictureFormat(PixelFormat.YCbCr_420_SP);
            //param.setPreviewSize(width, height);

            param.setPreviewSize(width, height);

            param.setFlashMode(Camera.Parameters.FOCUS_MODE_AUTO);
            if (!Build.MODEL.equals("KORIDY H30")) {
                param.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);// 1连续对焦
            } else {
                param.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
            }


            //<-处理变形
            int displayRotation = 0;
            WindowManager windowManager = (WindowManager)getSystemService(Context.WINDOW_SERVICE);
            int rotation = windowManager.getDefaultDisplay().getRotation();
            switch (rotation) {
                case Surface.ROTATION_0:
                    displayRotation = 0;
                    break;
                case Surface.ROTATION_90:
                    displayRotation = 90;
                    break;
                case Surface.ROTATION_180:
                    displayRotation = 180;
                    break;
                case Surface.ROTATION_270:
                    displayRotation = 270;
                    break;
            }
            Camera.CameraInfo info = new Camera.CameraInfo();
            Camera.getCameraInfo(0, info);
            int orientation;
            if (info.facing == Camera.CameraInfo.CAMERA_FACING_BACK) {
                orientation = (info.orientation - displayRotation + 360) % 360;
            } else {
                orientation = (info.orientation + displayRotation) % 360;
                orientation = (360 - orientation) % 360;
            }

            System.out.println("ImageFormat.getBitsPerPixel(ImageFormat.NV21)): " + ImageFormat.getBitsPerPixel(ImageFormat.NV21));

            //mCamera.addCallbackBuffer(new byte[((640 * 480) * ImageFormat.getBitsPerPixel(ImageFormat.NV21)) / 8]);
            //mCamera.addCallbackBuffer(new byte[((640 * 480) * ImageFormat.getBitsPerPixel(ImageFormat.RGB_565)) / 8]);
            //mCamera.addCallbackBuffer(frameBuffer); //Sets the image format for preview picture，默认为NV21
            //cameral.setPreviewCallbackWithBuffer()方法必须设置addCallbackBuffer(buffers)后onPreviewFrame()方法才会被持续调用

            //mCamera.setPreviewCallbackWithBuffer(this);

            mCamera.setPreviewCallback(this);

            mCamera.setParameters(param);
            mCamera.setDisplayOrientation(orientation);
            mCamera.setPreviewDisplay(surfaceHolder);
            mCamera.startPreview();

            //SendThread();

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void surfaceChanged(@NonNull SurfaceHolder surfaceHolder, int format, int width, int height) {
        Log.e(TAG,"surfaceChanged format:"+format+",width:"+width+",height:"+height);
        /*mCamera.autoFocus(new Camera.AutoFocusCallback() {
            @Override
            public void onAutoFocus(boolean success, Camera camera) {
                Log.e(TAG,"onAutoFocus success:"+success);
                if (success) {
                    mParameters = mCamera.getParameters();
                    mParameters.setPictureFormat(PixelFormat.JPEG); //图片输出格式
//                    mParameters.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);//预览持续发光
                    mParameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);//持续对焦模式
                    mCamera.setParameters(mParameters);
                    mCamera.startPreview();
                    mCamera.cancelAutoFocus();
                }
            }
        });*/
    }

    @Override
    public void surfaceDestroyed(@NonNull SurfaceHolder surfaceHolder) {
        Log.e(TAG,"surfaceDestroyed");
        if (mCamera != null) {
            mCamera.setPreviewCallback(null);   //切换摄像头时Camera is being used after Camera.release() was called
            mCamera.stopPreview();
            mCamera.release();
            mCamera = null;
        }
    }

    volatile boolean isDestroy = false;

    private ReentrantLock imageArrayLock = new ReentrantLock();
    @Override
    public void onPreviewFrame(byte[] bytes, Camera camera) {
        if (bytes == null) return;  //System.out.println("onPreviewFrame byte null");
        if (isDestroy) return;
        imageArrayLock.lock();
        rtcclient.SendNV21Image(bytes, width, height, bytes.length);
        imageArrayLock.unlock();

    }



    @Override
    protected void onDestroy() {
        super.onDestroy();
        stopRecorder();

        isDestroy = true;
    }
}


/*
0000000000435930 T Java_org_webrtc_audio_JavaAudioDeviceModule_nativeCreateAudioDeviceModule
0000000000435b4c T Java_org_webrtc_audio_WebRtcAudioRecord_nativeCacheDirectBufferAddress
0000000000435c9c T Java_org_webrtc_audio_WebRtcAudioRecord_nativeDataIsRecorded
0000000000436e98 T Java_org_webrtc_audio_WebRtcAudioTrack_nativeCacheDirectBufferAddress
0000000000437014 T Java_org_webrtc_audio_WebRtcAudioTrack_nativeGetPlayoutData
0000000000a223c4 T Java_org_webrtc_AudioTrack_nativeSetVolume
00000000005b8958 T Java_org_webrtc_BuiltinAudioDecoderFactoryFactory_nativeCreateBuiltinAudioDecoderFactory
00000000005b89a4 T Java_org_webrtc_BuiltinAudioEncoderFactoryFactory_nativeCreateBuiltinAudioEncoderFactory
0000000000a22430 T Java_org_webrtc_CallSessionFileRotatingLogSink_nativeAddSink
0000000000a224fc T Java_org_webrtc_CallSessionFileRotatingLogSink_nativeDeleteSink
0000000000a2253c T Java_org_webrtc_CallSessionFileRotatingLogSink_nativeGetLogData
0000000000a22e18 T Java_org_webrtc_DataChannel_nativeBufferedAmount
0000000000a22e80 T Java_org_webrtc_DataChannel_nativeClose
0000000000a22cd0 T Java_org_webrtc_DataChannel_nativeId
0000000000a22c50 T Java_org_webrtc_DataChannel_nativeLabel
0000000000a22b8c T Java_org_webrtc_DataChannel_nativeRegisterObserver
0000000000a22eac T Java_org_webrtc_DataChannel_nativeSend
0000000000a22cfc T Java_org_webrtc_DataChannel_nativeState
0000000000a22c08 T Java_org_webrtc_DataChannel_nativeUnregisterObserver
0000000000a23a1c T Java_org_webrtc_DtmfSender_nativeCanInsertDtmf
0000000000a23b28 T Java_org_webrtc_DtmfSender_nativeDuration
0000000000a23a40 T Java_org_webrtc_DtmfSender_nativeInsertDtmf
0000000000a23b38 T Java_org_webrtc_DtmfSender_nativeInterToneGap
0000000000a23ab0 T Java_org_webrtc_DtmfSender_nativeTones
0000000000664a60 T Java_org_webrtc_H264Utils_nativeIsSameH264Profile
00000000003a3b58 T Java_org_webrtc_Histogram_nativeAddSample
00000000003a3a98 T Java_org_webrtc_Histogram_nativeCreateCounts
00000000003a3b04 T Java_org_webrtc_Histogram_nativeCreateEnumeration
0000000000664acc T Java_org_webrtc_JavaI420Buffer_nativeCropAndScaleI420
00000000003a8000 T Java_org_webrtc_JniCommon_nativeAddRef
00000000003a8020 T Java_org_webrtc_JniCommon_nativeAllocateByteBuffer
00000000003a808c T Java_org_webrtc_JniCommon_nativeFreeByteBuffer
00000000003a8010 T Java_org_webrtc_JniCommon_nativeReleaseRef
00000000006638c8 T Java_org_webrtc_LibvpxVp8Decoder_nativeCreateDecoder
0000000000663914 T Java_org_webrtc_LibvpxVp8Encoder_nativeCreateEncoder
00000000008120f4 T Java_org_webrtc_LibvpxVp9Decoder_nativeCreateDecoder
0000000000812140 T Java_org_webrtc_LibvpxVp9Decoder_nativeIsSupported
0000000000812180 T Java_org_webrtc_LibvpxVp9Encoder_nativeCreateEncoder
00000000008121cc T Java_org_webrtc_LibvpxVp9Encoder_nativeIsSupported
00000000003a830c T Java_org_webrtc_Logging_nativeEnableLogThreads
00000000003a8314 T Java_org_webrtc_Logging_nativeEnableLogTimeStamps
00000000003a82f8 T Java_org_webrtc_Logging_nativeEnableLogToDebugOutput
00000000003a831c T Java_org_webrtc_Logging_nativeLog
0000000000818bac T Java_org_webrtc_MediaCodecVideoDecoder_nativeCreateDecoder
000000000081ceb4 T Java_org_webrtc_MediaCodecVideoEncoder_nativeCreateEncoder
000000000081cd74 T Java_org_webrtc_MediaCodecVideoEncoder_nativeFillInputBuffer
0000000000a25280 T Java_org_webrtc_MediaSource_nativeGetState
0000000000a253a8 T Java_org_webrtc_MediaStream_nativeAddAudioTrackToNativeStream
0000000000a253d0 T Java_org_webrtc_MediaStream_nativeAddVideoTrackToNativeStream
0000000000a25448 T Java_org_webrtc_MediaStream_nativeGetId
0000000000a253f8 T Java_org_webrtc_MediaStream_nativeRemoveAudioTrack
0000000000a25420 T Java_org_webrtc_MediaStream_nativeRemoveVideoTrack
0000000000a26038 T Java_org_webrtc_MediaStreamTrack_nativeGetEnabled
0000000000a25f48 T Java_org_webrtc_MediaStreamTrack_nativeGetId
0000000000a25fc0 T Java_org_webrtc_MediaStreamTrack_nativeGetKind
0000000000a26088 T Java_org_webrtc_MediaStreamTrack_nativeGetState
0000000000a2605c T Java_org_webrtc_MediaStreamTrack_nativeSetEnabled
00000000004da000 T Java_org_webrtc_Metrics_nativeEnable
00000000004da004 T Java_org_webrtc_Metrics_nativeGetAndReset
0000000000663b28 T Java_org_webrtc_NativeAndroidVideoTrackSource_nativeAdaptFrame
00000000006639dc T Java_org_webrtc_NativeAndroidVideoTrackSource_nativeAdaptOutputFormat
0000000000663d88 T Java_org_webrtc_NativeAndroidVideoTrackSource_nativeOnFrameCaptured
0000000000663984 T Java_org_webrtc_NativeAndroidVideoTrackSource_nativeSetState
00000000003a3b6c T Java_org_webrtc_NetworkMonitor_nativeNotifyConnectionTypeChanged
00000000003a3ca4 T Java_org_webrtc_NetworkMonitor_nativeNotifyOfActiveNetworkList
00000000003a3bbc T Java_org_webrtc_NetworkMonitor_nativeNotifyOfNetworkConnect
00000000003a3c5c T Java_org_webrtc_NetworkMonitor_nativeNotifyOfNetworkDisconnect
0000000000664dd8 T Java_org_webrtc_NV12Buffer_nativeCropAndScale
0000000000664ff0 T Java_org_webrtc_NV21Buffer_nativeCropAndScale
0000000000a26f3c T Java_org_webrtc_PeerConnection_nativeAddIceCandidate
0000000000a27054 T Java_org_webrtc_PeerConnection_nativeAddLocalStream
0000000000a27460 T Java_org_webrtc_PeerConnection_nativeAddTrack
0000000000a2772c T Java_org_webrtc_PeerConnection_nativeAddTransceiverOfType
0000000000a275e8 T Java_org_webrtc_PeerConnection_nativeAddTransceiverWithTrack
0000000000a26df0 T Java_org_webrtc_PeerConnection_nativeClose
0000000000a26d00 T Java_org_webrtc_PeerConnection_nativeConnectionState
0000000000a268b0 T Java_org_webrtc_PeerConnection_nativeCreateAnswer
0000000000a266f0 T Java_org_webrtc_PeerConnection_nativeCreateDataChannel
0000000000a267f0 T Java_org_webrtc_PeerConnection_nativeCreateOffer
0000000000a26e1c T Java_org_webrtc_PeerConnection_nativeCreatePeerConnectionObserver
0000000000a271d4 T Java_org_webrtc_PeerConnection_nativeCreateSender
0000000000a26e60 T Java_org_webrtc_PeerConnection_nativeFreeOwnedPeerConnection
0000000000a26604 T Java_org_webrtc_PeerConnection_nativeGetCertificate
0000000000a26434 T Java_org_webrtc_PeerConnection_nativeGetLocalDescription
0000000000a26410 T Java_org_webrtc_PeerConnection_nativeGetNativePeerConnection
0000000000a27350 T Java_org_webrtc_PeerConnection_nativeGetReceivers
0000000000a2651c T Java_org_webrtc_PeerConnection_nativeGetRemoteDescription
0000000000a272c8 T Java_org_webrtc_PeerConnection_nativeGetSenders
0000000000a273d8 T Java_org_webrtc_PeerConnection_nativeGetTransceivers
0000000000a26c88 T Java_org_webrtc_PeerConnection_nativeIceConnectionState
0000000000a26d78 T Java_org_webrtc_PeerConnection_nativeIceGatheringState
0000000000a27154 T Java_org_webrtc_PeerConnection_nativeNewGetStats
0000000000a270c4 T Java_org_webrtc_PeerConnection_nativeOldGetStats
0000000000a26fe8 T Java_org_webrtc_PeerConnection_nativeRemoveIceCandidates
0000000000a27090 T Java_org_webrtc_PeerConnection_nativeRemoveLocalStream
0000000000a275ac T Java_org_webrtc_PeerConnection_nativeRemoveTrack
0000000000a26af8 T Java_org_webrtc_PeerConnection_nativeSetAudioPlayout
0000000000a26b30 T Java_org_webrtc_PeerConnection_nativeSetAudioRecording
0000000000a26b68 T Java_org_webrtc_PeerConnection_nativeSetBitrate
0000000000a26e90 T Java_org_webrtc_PeerConnection_nativeSetConfiguration
0000000000a26970 T Java_org_webrtc_PeerConnection_nativeSetLocalDescription
0000000000a26a34 T Java_org_webrtc_PeerConnection_nativeSetRemoteDescription
0000000000a26c10 T Java_org_webrtc_PeerConnection_nativeSignalingState
0000000000a27854 T Java_org_webrtc_PeerConnection_nativeStartRtcEventLog
0000000000a278a0 T Java_org_webrtc_PeerConnection_nativeStopRtcEventLog
0000000000a2df78 T Java_org_webrtc_PeerConnectionFactory_nativeCreateAudioSource
0000000000a2e014 T Java_org_webrtc_PeerConnectionFactory_nativeCreateAudioTrack
0000000000a2de54 T Java_org_webrtc_PeerConnectionFactory_nativeCreateLocalMediaStream
0000000000a2db7c T Java_org_webrtc_PeerConnectionFactory_nativeCreatePeerConnection
0000000000a2d9d4 T Java_org_webrtc_PeerConnectionFactory_nativeCreatePeerConnectionFactory
0000000000a2ded4 T Java_org_webrtc_PeerConnectionFactory_nativeCreateVideoSource
0000000000a2def0 T Java_org_webrtc_PeerConnectionFactory_nativeCreateVideoTrack
0000000000a2e1c4 T Java_org_webrtc_PeerConnectionFactory_nativeDeleteLoggable
0000000000a2d8a8 T Java_org_webrtc_PeerConnectionFactory_nativeFindFieldTrialsFullName
0000000000a2e0d8 T Java_org_webrtc_PeerConnectionFactory_nativeFreeFactory
0000000000a2e118 T Java_org_webrtc_PeerConnectionFactory_nativeGetNativePeerConnectionFactory
0000000000a2d7ac T Java_org_webrtc_PeerConnectionFactory_nativeInitializeAndroidGlobals
0000000000a2d7e0 T Java_org_webrtc_PeerConnectionFactory_nativeInitializeFieldTrials
0000000000a2d930 T Java_org_webrtc_PeerConnectionFactory_nativeInitializeInternalTracer
0000000000a2e120 T Java_org_webrtc_PeerConnectionFactory_nativeInjectLoggable
0000000000a2e210 T Java_org_webrtc_PeerConnectionFactory_nativePrintStackTrace
0000000000a2e26c T Java_org_webrtc_PeerConnectionFactory_nativePrintStackTracesOfRegisteredThreads
0000000000a2d934 T Java_org_webrtc_PeerConnectionFactory_nativeShutdownInternalTracer
0000000000a2e09c T Java_org_webrtc_PeerConnectionFactory_nativeStartAecDump
0000000000a2d938 T Java_org_webrtc_PeerConnectionFactory_nativeStartInternalTracingCapture
0000000000a2e0c8 T Java_org_webrtc_PeerConnectionFactory_nativeStopAecDump
0000000000a2d9d0 T Java_org_webrtc_PeerConnectionFactory_nativeStopInternalTracingCapture
0000000000a2f2e8 T Java_org_webrtc_RtcCertificatePem_nativeGenerateCertificate
0000000000a33410 T Java_org_webrtc_RtpReceiver_nativeGetId
0000000000a33378 T Java_org_webrtc_RtpReceiver_nativeGetParameters
0000000000a332a8 T Java_org_webrtc_RtpReceiver_nativeGetTrack
0000000000a33548 T Java_org_webrtc_RtpReceiver_nativeSetFrameDecryptor
0000000000a33488 T Java_org_webrtc_RtpReceiver_nativeSetObserver
0000000000a33300 T Java_org_webrtc_RtpReceiver_nativeSetParameters
0000000000a334fc T Java_org_webrtc_RtpReceiver_nativeUnsetObserver
0000000000a33978 T Java_org_webrtc_RtpSender_nativeGetDtmfSender
0000000000a33b1c T Java_org_webrtc_RtpSender_nativeGetId
0000000000a33a84 T Java_org_webrtc_RtpSender_nativeGetParameters
0000000000a33920 T Java_org_webrtc_RtpSender_nativeGetTrack
0000000000a33b94 T Java_org_webrtc_RtpSender_nativeSetFrameEncryptor
0000000000a339d0 T Java_org_webrtc_RtpSender_nativeSetParameters
0000000000a338f8 T Java_org_webrtc_RtpSender_nativeSetTrack
0000000000a33fa4 T Java_org_webrtc_RtpTransceiver_nativeCurrentDirection
0000000000a33f38 T Java_org_webrtc_RtpTransceiver_nativeDirection
0000000000a33d28 T Java_org_webrtc_RtpTransceiver_nativeGetMediaType
0000000000a33d94 T Java_org_webrtc_RtpTransceiver_nativeGetMid
0000000000a33e90 T Java_org_webrtc_RtpTransceiver_nativeGetReceiver
0000000000a33e0c T Java_org_webrtc_RtpTransceiver_nativeGetSender
0000000000a340a4 T Java_org_webrtc_RtpTransceiver_nativeSetDirection
0000000000a34094 T Java_org_webrtc_RtpTransceiver_nativeStop
0000000000a33f14 T Java_org_webrtc_RtpTransceiver_nativeStopped
00000000006653c8 T Java_org_webrtc_TimestampAligner_nativeCreateTimestampAligner
00000000006653f4 T Java_org_webrtc_TimestampAligner_nativeReleaseTimestampAligner
00000000006653c4 T Java_org_webrtc_TimestampAligner_nativeRtcTimeNanos
0000000000665424 T Java_org_webrtc_TimestampAligner_nativeTranslateTimestamp
0000000000a360b8 T Java_org_webrtc_TurnCustomizer_nativeFreeTurnCustomizer
0000000000666218 T Java_org_webrtc_VideoDecoderFallback_nativeCreateDecoder
00000000006662f8 T Java_org_webrtc_VideoDecoderWrapper_nativeOnDecodedFrame
00000000006684c8 T Java_org_webrtc_VideoEncoderFallback_nativeCreateEncoder
00000000006685a8 T Java_org_webrtc_VideoEncoderWrapper_nativeOnEncodedFrame
000000000066b180 T Java_org_webrtc_VideoTrack_nativeAddSink
000000000066b22c T Java_org_webrtc_VideoTrack_nativeFreeSink
000000000066b1d0 T Java_org_webrtc_VideoTrack_nativeRemoveSink
000000000066b1e4 T Java_org_webrtc_VideoTrack_nativeWrapSink
000000000066b244 T Java_org_webrtc_YuvHelper_nativeCopyPlane
000000000066b2cc T Java_org_webrtc_YuvHelper_nativeI420Copy
000000000066b510 T Java_org_webrtc_YuvHelper_nativeI420Rotate
000000000066b404 T Java_org_webrtc_YuvHelper_nativeI420ToNV12

 */